package ProyectoX;

import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JLabel;

/*
 * clase publica nivel
 */
public class Nivel  {
	
	protected NaveJugador MiNave;
	protected Logica juego;
	protected ArrayList<NaveEnemiga> Enemigos;
	protected ArrayList<NaveEnemiga> NavesEnemigasEliminar;
	
	protected ArrayList<ArmaEnemiga> ArmasEnemigas;
	protected ArrayList<ArmaEnemiga> ArmasEnemigasEliminar;
	
	protected ArrayList<PowerUp> PowerUps;
	protected ArrayList<PowerUp> PowerUpsEliminar;
	
	protected ArrayList<ArmaJugador> ArmasJugador;
	protected ArrayList<ArmaJugador> ArmasJugadorEliminar;
	
	protected ArrayList<Bomba> Bombas;
	protected ArrayList<Bomba> BombasEliminar;

	protected NaveEnemiga Final;
	
	protected int cantBombas;
	
	protected boolean pausa;
	
	protected Hilo Hilo;
	protected HiloArmas HiloArmas;
	protected HiloPowerUps HiloPU;
	
	/*
	 * constructor.Inicializa los atributos y crea las listas. Las bombas se inicializan con 2.
	 */
	public Nivel(){
		
		Enemigos = new ArrayList<NaveEnemiga>();
		NavesEnemigasEliminar = new ArrayList<NaveEnemiga>();
		
		ArmasEnemigas = new ArrayList<ArmaEnemiga>();
		ArmasEnemigasEliminar = new ArrayList<ArmaEnemiga>();
		
		PowerUps = new ArrayList<PowerUp>();
		PowerUpsEliminar = new ArrayList<PowerUp>();
		
		ArmasJugador = new ArrayList<ArmaJugador>();
		ArmasJugadorEliminar = new ArrayList<ArmaJugador>();
		
		Bombas = new ArrayList<Bomba>();			
		
		Final = new Pulpo(this);
		
		pausa = false;
		
		Hilo = new Hilo(this);
		
		HiloPU = new HiloPowerUps(this);
		
		HiloArmas = new HiloArmas(this);
		
		cantBombas = 2;
		
		
		
	}
	
	
	/*
	 * Metodo publico que se encarga de manejar la estructura del juego en cuanto a los enemigos, power ups y elementos
	 * que se inserten en pantalla en un determinado momento en el juego. Da start a todos los hilos del juego.
	 */
	public void Juego(){
		
		CargarFase (800, 100);	

		agregarNaveEnemiga(Final, 8200, 200);
		
		Hilo.start();
		HiloPU.start();
		HiloArmas.start();
			
	}
	
	
	/*
	 * metodo privado que se encarga de agregar una determinada cantidad de peces en el panel del juego
	 */
	private void CargarFase(int x, int y){		
		int x2 = x;
		
		for(int i = 0; i<2 ; i++){
			NaveEnemiga n = new Pez(this);
			agregarNaveEnemiga(n, x, y);
			x += 602;
			y += 105;							
		}

		y = 420;
		
		for(int i = 0; i<3 ; i++){
			NaveEnemiga n= new Pez(this);
			agregarNaveEnemiga(n, x2, y);
			x2 += 550;
			y -= 120;
		}
		
		Bomba b2 = new Bomba(this);
		preparar(b2, x*2, y);
		
		y = 100;
		
		CargarFase2(x - 300, y);
		CargarFase2(4700, 140);
	}
	
	
	/*
	 * metodo privado que se encarga de agregar una determinada cantidad de peces y cangrejos en el panel del juego
	 */
	private void CargarFase2 (int x, int y){
		
		int x2 = x;
		
		for(int i = 0; i<2 ; i++){
			NaveEnemiga n= new Cangrejo(this);
			agregarNaveEnemiga(n, x, y);
			x += 702;
			y += 125;							
		}
		
		y = 400;
		for(int i = 0; i<3 ; i++){
			NaveEnemiga n= new Pez(this);
			agregarNaveEnemiga(n, x2, y);
			x2 += 300;
			y -= 40;
		}
		
		Bomba b2 = new Bomba(this);
		preparar(b2, x-600, y);
	
		
		y = 90;
		
		CargarFase3(x - 300, 100);
	}

	
	/*
	 * metodo privado que se encarga de agregar una determinada cantidad de peces, cangrejos y tiburones en el panel del juego
	 */
	private void CargarFase3 (int x, int y){	
		int x2 = x;
		for(int i = 0; i<3 ; i++){
			NaveEnemiga n = new Tiburon(this);
			agregarNaveEnemiga(n, x, y);
			x += 402;
			y += 102;							
		}
		
		for(int i = 0; i<3 ; i++){
			NaveEnemiga n = new Tiburon(this);
			agregarNaveEnemiga(n, x, y);
			
			x += 200;
			y -= 72;							
		}
		
		x = x - 502*2;
		y = 350;
		for(int i = 0; i<5 ; i++){
			NaveEnemiga n= new Cangrejo(this);
			agregarNaveEnemiga(n, x, y);
			
			x += 250;
			y -= 60;	
		}
		
		Bomba b = new Bomba(this);
		preparar(b, x-500, y+100);
		
		for (int i = 0; i<5; i++){
			NaveEnemiga n = new Pez(this);
			agregarNaveEnemiga(n, x2, y);
			x2 += 350;
			y += 59;
		}
	
	}
	
	/*
	 * setea la nave principal con la que se jugara en el juego.La prepara en la posicion inicial 
	 */
	public void elegirNavePcipal(NaveJugador n){
		MiNave= n;
		preparar();
	}
	
	/*
	 * Agrega una nave enemiga a la lista y la prepara en el panel de juego.
	 */
	protected void agregarNaveEnemiga(NaveEnemiga n, int x, int y){
		Enemigos.add(n);
		n.setBounds(0, 0, n.getIcon().getIconWidth(), n.getIcon().getIconHeight());
		preparar(n, x, y);
	}
	
	
	/*
	 * Agrega un componente dibujable al panel de juego
	 */
	public void agregarComponente(Dibujable c){
	    juego.jPanelNivel.add(c);	 
	}
	
	
	/*
	 * Retorna el puntaje de la nave jugador.
	 */
	public int obtenerPuntaje(){
		return MiNave.obtenerPuntaje();
	}
	
	/*
	 * Retorna la nave jugador
	 */
	public NaveJugador obtenerNaveJugador(){
		return MiNave;
	}
	
	/*
	 * Retorna la lista de naves enemigas del juego
	 */
	public ArrayList<NaveEnemiga> obtenerNavesEnemigas(){
		return Enemigos;
	}
	
	
	/*
	 * Retorna la lista de bombas del juego
	 */
	public ArrayList<Bomba> obtenerBombas(){
		return Bombas;
	}
	
	
	/*
	 * Retorna la lista de power ups del juego
	 */
	public ArrayList<PowerUp> obtenerPowerUps(){
		return PowerUps;
	}
	
	
	/*
	 * Retorna la lista de armas enemigas del juego
	 */
	public ArrayList<ArmaEnemiga> obtenerArmasEnemigas(){
		return ArmasEnemigas;
	}
	
	
	/*
	 * Retorna la lista de armas jugador del juego
	 */
	public ArrayList<ArmaJugador> obtenerArmasJugador(){
		return ArmasJugador;
	}	
	
	/*
	 * Retorna la logica del juego
	 */
	public Logica obtenerJuego(){
		return juego;
	}
	
	/*
	 * Setea a nave del jugador, armas jugador, las naves enemigas,armas enemigas, los power ups 
	 * la nave jefe y las bombas en no visible. Llama al metodo ranking .
	 */
	public void Terminar(){
		
		MiNave.setVisible(false);
		
		for(ArmaJugador arma: ArmasJugador){
			arma.setVisible(false);
		}
		
		for(NaveEnemiga nave: Enemigos){
			nave.setVisible(false);		
		}
		
		for(ArmaEnemiga arma: ArmasEnemigas){
			arma.setVisible(false);	
		}
		
		for(PowerUp pu: PowerUps){
			pu.setVisible(false);
		}
		
		for(Bomba b: Bombas){
			b.setVisible(false);
		}
		
		Final.setVisible(false);
		
		juego.fondo.Visible();
		
		juego.initRanking();
		
	}
	
	
	/*
	 * Inserta en el panel de juego una nave enemiga con una posicion dada.
	 */
	protected void preparar(NaveEnemiga n, int x, int y) {
		if (y <= obtenerJuego().PanelPuntos.getHeight())
			y = n.getHeight();
		else
			if (y + n.getHeight() >= obtenerAltoNivel())
				y = obtenerAltoNivel() - n.getHeight();
				
		n.setLocation(x,y);
		juego.jPanelNivel.add(n);
	}
	
	
	/*
	 * Inserta en el panel de juego una bomba con una posicion dada.
	 */
	protected void preparar(Bomba b, int x, int y) {
		b.setBounds(x,y, b.getIcon().getIconWidth(), b.getIcon().getIconHeight());
		this.obtenerBombas().add(b);
		juego.jPanelNivel.add(b);
	}
	
	/*
	 * Inserta en el panel de juego la nave jugador con una posicion establecida.
	 */
	protected void preparar() {
		int mitad = juego.getHeight() / 2;
		this.MiNave.setLocation(MiNave.getWidth()/2 -40, mitad-(MiNave.getWidth()/2));
		juego.jPanelNivel.add(MiNave.obtenerAgua());
		
	}
	
	/*
	 * setea el juego
	 */
	public void setJuego(Logica juego) {
		this.juego = juego;
	}
	
	/*
	 * Retorna el ancho del frame del nivel
	 */
	public int obtenerAnchoNivel(){
		return 850;
	}

	/*
	 * Retorna el alto del frame del nivel
	 */
	public int obtenerAltoNivel(){
		return 550;
	}
	
	/*
	 * Retorna la cantidad actual de bombas 
	 */
	public int cantBombas(){
		return cantBombas;
	}
	
	
	/*
	 * Aumenta la cantidad actual de bombas
	 */
	public void AgregarBomba(){
		 cantBombas++;
	}
	
	/*
	 * Disminuye la cantidad actual de bombas. Si el resultado es menor a cero la cantidad es cero.
	 */
	public void QuitarBomba(){
		cantBombas --;
		if (cantBombas<0)
			cantBombas = 0;
	}

	/*
	 * Retorna la nave final o jefe del juego
	 */
	public NaveEnemiga obtenerNaveFinal(){
		return Final;
	}
	
	/*
	 * Retorna true si el nivel esta en pausa, false en caso contrario
	 */
	public boolean Pausa(){
		return pausa;
	}
	
	/*
	 * Cambia pausa a su estado contrario (true si era false, false si era true).
	 */
	public void setPausa(){
		if (pausa == true)
			pausa = false;
		else
			pausa = true;
	}


}


